<?php 
namespace App\Http\Controllers\Api\v1\Check;

use App\Tools\Base\Auth;
use App\Models\Api\User;
use App\Exceptions\ApiException;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Input;

use Db,Request;
/**
* 接口调用验证
*/
class CheckController extends Auth
{
    const TOKEN = 'zhunleappv_1.1.0';
    public $func = 'CheckAccessTokenSafe';

	public  function __construct()
	{    
	  if(!IS_CLI){
        
        $this->filter_xss();
	    $param = Request::all();
        $header=Request::header();
        
	    if(!isset($header['sign']))
	    {
            if(!defined('IS_ACCESS_TOKEN_CHECKED'))
            {
                if($this->func == 'CheckAccessTokenSafe')
                {
                    $accessTokenStatusSafe = $this->CheckAccessTokenSafe();

                    if($accessTokenStatusSafe['code'] != 200)
                    {
                        echo json_encode($accessTokenStatusSafe);exit;
                    }
                }
                if($this->func == 'check')
                {
                    $check = $this->check();

                    if($check['code'] != 200)
                    {
                        echo json_encode($check);exit;
                    }
                }
            }
            if(isset($param['ucid']))
            {
                $map = ['uc_id' => $param['ucid']];
                $this->user = (new User())->getUserinfo($map);
              
            }
        }
        else
        {
            parent::__construct();
        }
	}
}
	public  function check_func($func = 'CheckAccessTokenSafe')
    {
        $this->func = $func;
    }

	public function filter_xss()
    {
        $agent = Request()->header('user-agent');// sqlmap
        if(
            in_array(Request()->ip(),[
                '114.205.60.218',
            ])
            || in_array(htmlspecialchars(Request::get('ucid')),[
                    'd27d9cf444c3be10aeac75fa5004742e',
                    '9057fe42ac42513b36c9b54008301530',
                ])
            || strpos($agent,'sqlmap') !== false
            || strpos($agent,'AppEngine-Google') !== false
            || strpos($agent,'appid')
        )

            throw new ApiException('404 NOT FOUND', 404);
    }


	public function CheckAccessTokenSafe()
    {
        $access_token = privDecrypt(Request::get('access_token'));

        if(!$access_token)
        {
            return ['code'=>10107,'msg'=>'Access_token not exist.'];
        }

        $data = Appid::where(["app_accesstoken"=>$access_token]) -> first();

        if(empty($data) || $data['app_expire'] + $data['app_gettime'] < time())
        {
            return ['code'=>10108,'msg'=>'Access_token Expired.'];
        }

        if($data['app_status'] != 1)
        {
            return ['code'=>10109,'msg'=>'Premission Dined.'];
        }
        define('IS_ACCESS_TOKEN_CHECKED',true);
        return ['code'=>200,'msg'=>'ok'];
    }

    public function check()
    {
        //验证身份
        $timeStamp = Input::get('timeStamp');// 时间戳
        $randomStr = Input::get('randomStr');// 随机字符串
        $signature = Input::get('access_token');// 签名
        $str = $this -> arithmetic($timeStamp,$randomStr);
        if($str != $signature){
            return ['code'=>10107,'msg'=>'Auth failed.'];
        }
        return ['code'=>200,'msg'=>'ok'];
    }

    /**
     * 签名算法
     * @param $timeStamp 时间戳
     * @param $randomStr 随机字符串
     * @return string 返回签名
     */
    protected function arithmetic($timeStamp,$randomStr){
        $arr['timeStamp'] = $timeStamp;
        $arr['randomStr'] = $randomStr;
        $arr['token'] = self::TOKEN;// 口令
        //按照首字母大小写顺序排序
        sort($arr,SORT_STRING);
        //拼接成字符串
        $str = implode($arr);
        //进行加密
        $signature = sha1($str);
        $signature = md5($signature);
        //转换成大写
        $signature = strtoupper($signature);
        return $signature;
    }

    /**
     * 检查档案时间格式
     * @param $year
     * @param $month
     * @param $day
     * @param $hour
     * @param $minute
     * @param $timezone
     */
	public function checkRecodeData($year=null,$month=null,$day=null,$hour=null,$minute=null,$timezone=null)
    {
        // 年份限制 1900 - 2099
        if($year === null || $year < 1000 || $year > 2399)
        {
//            echo $year;
            throw new ApiException('年份无效', 200);
        }
        // 月份限制 1-12
        if($month === null || $month < 0 || $month > 12)
        {
             throw new ApiException('月份无效', 200);
        }
        // 日期限制 1-31
        if($day === null || $day < 0 || $day > 31
            || ($this->is_bissextile($year) && $month == 2 && $day > 29)
            || (!$this->is_bissextile($year) && $month == 2 && $day > 28)
            || (in_array($month,[4,6,9,11]) && $day > 30))
        {
            throw new ApiException('日期中天数无效', 200);
        }
        // 小时限制 0-23
        if($hour === null || $hour < 0 || $hour > 23)
        {
            throw new ApiException('小时无效', 200);
        }
        // 分钟限制 0-59
        if($minute === null || $minute < 0 || $minute > 59)
        {
            throw new ApiException('分钟无效', 200);
        }
        if( $timezone < -12 || $timezone > 12)
        {
            throw new ApiException('当前时区无效', 200);
        }
    }
    /**
     * 判断是否为闰年
     * 闰年 true || 平年 false
     * @param null $year
     * @return bool
     */
    private function is_bissextile($year = null)
    {
        if($year === null)
        {
            throw new ApiException('年份无效', 200);
        }
        if($year % 400 === 0 || ($year % 100 !== 0 && $year % 4 === 0))
        {
            return true;
        }
        return false;
    }
}